package com.amsp.oa.oademo.service.impl;

import com.amsp.oa.oademo.entity.TrainingSignIn;
import com.amsp.oa.oademo.entity.TrainingSignInDetail;
import com.amsp.oa.oademo.mapper.TrainingSignInMapper;
import com.amsp.oa.oademo.mapper.TrainingSignInDetailMapper;
import com.amsp.oa.oademo.service.TrainingSignInService;
import com.amsp.oa.oademo.vo.TrainingSignInVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class TrainingSignInServiceImpl implements TrainingSignInService {

    @Resource
    private TrainingSignInMapper trainingSignInMapper;

    @Resource
    private TrainingSignInDetailMapper trainingSignInDetailMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveTrainingSignIn(TrainingSignInVO trainingSignInVO) {
        TrainingSignIn trainingSignIn = new TrainingSignIn();
        BeanUtils.copyProperties(trainingSignInVO, trainingSignIn);

        if (trainingSignInVO.getId() != null) {
            trainingSignInMapper.updateById(trainingSignIn);
            trainingSignInDetailMapper.delete(
                    new LambdaQueryWrapper<TrainingSignInDetail>()
                            .eq(TrainingSignInDetail::getTrainingId, trainingSignIn.getId()));
        } else {
            trainingSignInMapper.insert(trainingSignIn);
        }

        if (trainingSignInVO.getEmployees() != null && !trainingSignInVO.getEmployees().isEmpty()) {
            List<TrainingSignInDetail> details = trainingSignInVO.getEmployees().stream()
                    .map(employee -> {
                        TrainingSignInDetail detail = new TrainingSignInDetail();
                        BeanUtils.copyProperties(employee, detail);
                        detail.setTrainingId(trainingSignIn.getId());
                        return detail;
                    })
                    .collect(Collectors.toList());
            details.forEach(trainingSignInDetailMapper::insert);
        }
    }

    @Override
    public TrainingSignInVO getTrainingSignInById(Long id) {
        TrainingSignIn trainingSignIn = trainingSignInMapper.selectById(id);
        if (trainingSignIn == null) {
            return null;
        }

        TrainingSignInVO vo = new TrainingSignInVO();
        BeanUtils.copyProperties(trainingSignIn, vo);

        List<TrainingSignInDetail> details = trainingSignInDetailMapper.selectList(
                new LambdaQueryWrapper<TrainingSignInDetail>()
                        .eq(TrainingSignInDetail::getTrainingId, id));

        vo.setEmployees(details.stream()
                .map(detail -> {
                    TrainingSignInVO.EmployeeVO employeeVO = new TrainingSignInVO.EmployeeVO();
                    BeanUtils.copyProperties(detail, employeeVO);
                    return employeeVO;
                })
                .collect(Collectors.toList()));

        return vo;
    }

    @Override
    public IPage<TrainingSignInVO> getTrainingSignInList(Page<TrainingSignInVO> page, String keyword) {
        Page<TrainingSignIn> dataPage = new Page<>(page.getCurrent(), page.getSize());

        LambdaQueryWrapper<TrainingSignIn> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.hasText(keyword)) {
            wrapper.like(TrainingSignIn::getTrainingLocation, keyword);
        }

        IPage<TrainingSignIn> result = trainingSignInMapper.selectPage(dataPage, wrapper);

        IPage<TrainingSignInVO> voPage = new Page<>(result.getCurrent(), result.getSize(), result.getTotal());
        voPage.setRecords(result.getRecords().stream()
                .map(this::convertToVO)
                .collect(Collectors.toList()));

        return voPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteTrainingSignIn(Long id) {
        trainingSignInDetailMapper.delete(
                new LambdaQueryWrapper<TrainingSignInDetail>()
                        .eq(TrainingSignInDetail::getTrainingId, id));
        trainingSignInMapper.deleteById(id);
    }

    private TrainingSignInVO convertToVO(TrainingSignIn entity) {
        TrainingSignInVO vo = new TrainingSignInVO();
        BeanUtils.copyProperties(entity, vo);
        return vo;
    }
}